#include "EventHandlerAgentConnection.hpp"
#include "EventHandlerTrayConnection.hpp"
#include"WorkNodeManger.hpp"
#include "TheApp.hpp"
#include "MasterClient.hpp"
#include "TaskManager.hpp"
#include "cybertron/core/UtilStateHelper.hpp"
EventHandlerAgentConnection::EventHandlerAgentConnection()
{
	//recv 

	mWorkNodeId.empty();
	//send

	mMessageRouter.registerHandler(
		Agent::ENodeRegisterAtAgent,
		[this](Message& msg) {
		onFromWorkNodeRegister(msg);
	});

	mMessageRouter.registerHandler(
		Agent::EWorkNodeStateSync,
		[this](Message& msg) {
		onFromWorkNodeStateSync(msg);
	});

	mMessageRouter.registerHandler(
		Agent::EStopTaskFromWorkNode,
		[this](Message& msg) {
		onFromWorkNodeStopTask(msg);
	});

	mMessageRouter.registerHandler(
		Agent::ECommandFromWorkNode,
		[this](Message& msg) {
		onFromWorkNodeCommandRet(msg);
	});

	mMessageRouter.registerHandler(
		Common::ESyncWorkNodeDynamicConfig,
		[this](Message& msg) {
		onFromWorkSyncWorkNodeDynamicConfig(msg);
	});

	mMessageRouter.registerHandler(
		Agent::EWorkNodeGetDynamicConfigFromAgent,
		[this](Message& msg) {
		onFromWorkGetDynamicConfig(msg);
	});

	mMessageRouter.registerHandler(
		Agent::EGetAgentInitInfo,
		[this](Message& msg) {
		onFromTrayGetAgentInitInfo(msg);
	});

}

EventHandlerAgentConnection::~EventHandlerAgentConnection()
{
}

void EventHandlerAgentConnection::onDisposed()
{
}

void EventHandlerAgentConnection::onDisconnected()
{
	if (mWorkNodeId.size() > 0) {
		//check 
		//1:process is exit
		//2:end task 
#if defined(NDEBUG)
		WorkNodeManger::GetInstance().SetWorkNodeState(mWorkNodeId, Common::EWorkNodeStateEndingWork);
#endif
	}
}

void EventHandlerAgentConnection::onConnected()
{
}

void EventHandlerAgentConnection::onMessage(Message& msg)
{
	mMessageRouter.onMessage(msg);
}

void EventHandlerAgentConnection::onFromWorkNodeRegister(Message& msg)
{
	Agent::WorkNodeRegister data;

	if (!msg.toProtobuf(data))
	{
		close("Protocol error!");

		return;
	}
	if (data.worktype() == Common::EWorkNodeType_None) {
		EventHandlerTrayConnection::GetInstance().onFromNodeRegisterAtTray(getSocket());
		//WorkNodeManger::GetInstance().SetTrayNodeSocket(data.worknodeid(), getSocket());
		return;
	}
	mWorkType = data.worktype();
	mWorkNodeId = data.worknodeid();
	mVersion = data.version();
	mDesc = data.desc();
	mParam = data.param();
	mTaskId = data.taskid();
	string worldJson;
	string workJson;
	Common::ESimOneErrorCode Code = Common::ESimOneOK;
	bool ret = TaskManager::GetInstance().getTaskWorkJson(mTaskId, mWorkNodeId, worldJson, workJson);
	if (!ret) {
		Code = Common::ESimOneNotFindWorkNode;
	}
	Master::TaskStartFromCommander* pStartTaskConfig = TaskManager::GetInstance().getTaskStartFromCommander(mTaskId);

	WorkNodeManger::GetInstance().SetWorkNodeSocket(mWorkNodeId, getSocket());
	WorkNodeManger::GetInstance().SetWorkNodeTaskId(mWorkNodeId, mTaskId);
	WorkNodeManger::GetInstance().SetWorkNodeState(mWorkNodeId, Common::EWorkNodeStateStarted);
	WorkNodeManger::GetInstance().SetWorkNodeStatus(mWorkNodeId, Common::EWorkNodeStatusWorking);

	WorkNodeManger::GetInstance().SendWorkNodeRegisterRet(mTaskId, pStartTaskConfig, Code, "", getSocket());
	string name = UtilStateHelper::GetInstance().GetWorkNodeName(mWorkType);
	//logInfo("[AgentFromWork]onFromWorkNodeRegister worktype:%s work id:%s ", name.c_str(),mWorkNodeId.c_str());
}

void EventHandlerAgentConnection::onFromWorkNodeStateSync(Message& msg) {
	Agent::WorkNodeStateSync data;

	if (!msg.toProtobuf(data))
	{
		close("Protocol error!");

		return;
	}

	WorkNodeManger::GetInstance().SetWorkNodeState(mWorkNodeId, data.workstate());
	//logInfo("[AgentFromWork]onFromWorkNodeStateSync work id:%s state:%d", mWorkNodeId.c_str(),data.workstate());
	return;
}


void EventHandlerAgentConnection::onFromWorkNodeCommandRet(Message& msg) {
	logInfo("[AgentFromWork]onFromWorkNodeCommandRet work id:%s", mWorkNodeId.c_str());
}

void EventHandlerAgentConnection::onFromWorkSyncWorkNodeDynamicConfig(Message& msg) {
	Common::SyncWorkNodeDynamicConfig data;

	if (!msg.toProtobuf(data))
	{
		close("Protocol error!");

		return;
	
	}
	string name = UtilStateHelper::GetInstance().GetWorkNodeName(data.worknodetype());
	logInfo("[AgentFromWork]onFromWorkSyncWorkNodeDynamicConfig[%s] work id:%s,port:%d", name.c_str(), mWorkNodeId.c_str(), data.workpublicport());
	if (theApp->getMasterClient()) {
		theApp->getMasterClient()->Send2MasterSycnWorkNodeDynamicConfig(&data);
	}

	
}

void EventHandlerAgentConnection::onFromWorkGetDynamicConfig(Message& msg) {
	Agent::WorkNodeGetDynamicConfigFromAgent data;

	if (!msg.toProtobuf(data))
	{
		close("Protocol error!");

		return;
	}
	string task_id = data.taskid();
	string workNodeId = data.workid();
	Common::EWorkNodeType workType = data.worktype();
	Common::SyncWorkNodeDynamicConfig config ;
	

	string dstName = UtilStateHelper::GetInstance().GetWorkNodeName(workType);
	string srcName = UtilStateHelper::GetInstance().GetWorkNodeName(mWorkType);

	if (!TaskManager::GetInstance().getSyncWorkNodeDynamicConfig(task_id, workNodeId, workType, &config)) {
		//logError("[AgentFromWork]onFromWorkGetDynamicConfig[%s===>%s] empty", srcName.c_str(), dstName.c_str());
		return;
	}
	SocketBasePtr pSocket= getSocket();
	pSocket->send(Agent::EWorkNodeGetDynamicConfigRetFromAgent, config);

	//logInfo("[AgentFromWork]onFromWorkGetDynamicConfig[%s===>%s:%s:%d] sucessful", srcName.c_str(), dstName.c_str(), 
	//	config.workpublicip().c_str(),config.workpublicport());

}
void EventHandlerAgentConnection::onFromWorkNodeStopTask(Message& msg) {
	Agent::StopTaskFromWorkNode data;

	if (!msg.toProtobuf(data))
	{
		close("Protocol error!");

		return;
	}
	string taskId = data.taskid();
	string workNodeId = data.workid();
	Common::EWorkNodeType workType = mWorkType;
	
	logInfo("[AgentFromWork]onFromWorkNodeStopTask work id:%s, work type:%s", mWorkNodeId.c_str(), UtilStateHelper::GetInstance().GetWorkNodeName(mWorkType).c_str());

	Common::ETaskEndReason reason = data.reason();
	if (theApp->getMasterClient()) {
		theApp->getMasterClient()->Send2MasterStopTask("WorkExitMessage", taskId, workNodeId, workType, reason);
	}
	
	
	return;
}

void EventHandlerAgentConnection::onFromTrayGetAgentInitInfo(Message& msg) {
	EventHandlerTrayConnection::GetInstance().onFromTrayGetAgentInitInfo(msg);
}